package com.example.chatroom.socket;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.chatroom.domain.ChatHistory;
import com.example.chatroom.dto.SimpleUserRole;
import com.example.chatroom.service.ChatService;
import com.example.chatroom.service.UserInfoService;
import com.example.chatroom.service.impl.ChatServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
import org.springframework.web.socket.server.standard.SpringConfigurator;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.sql.Timestamp;
import java.util.*;


/**
 * messageType 1代表上线 2代表下线 3代表普通消息 4代表禁言
 */
@Component
@ServerEndpoint(value = "/websocket/{username}")
public class WebSocket {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    private static ChatService chatService;
    private static UserInfoService userInfoService;

    @Autowired
    public void setChatService(ChatService chatService, UserInfoService userInfoService) {
        WebSocket.chatService = chatService;
        WebSocket.userInfoService = userInfoService;
    }

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }


    private static int onlineCount = 0;

    private static Map<String, WebSocket> clients = new HashMap<>(16);

    private String username;

    private Session session;

    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session) {
        logger.info("session ID:{}",session.getId());
        JSONArray jsonArray = new JSONArray();
        this.session = session;
        this.username = username;
        addOnlineCount();
        logger.info("有新连接加入！ 当前在线人数{}",onlineCount);
        Map<String,Object> map = new HashMap<>(16);
        clients.put(username, this);
        map.put("messageType", 1);
        map.put("fromUsername", username);
        for (String s : clients.keySet()) {
            SimpleUserRole simpleUserRole = userInfoService.getUserState(s);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("username", s);
            jsonObject.put("state", simpleUserRole.getState());
            jsonObject.put("role", simpleUserRole.getRole());
            jsonArray.add(jsonObject);
        }
        map.put("onlineUsers", jsonArray);
        sendMessageToAll(JSON.toJSONString(map), username);
    }

    @OnClose
    public void onClose()
    {
        subOnlineCount();
        clients.remove(username);
        Map<String,Object> map = new HashMap<>(16);
        map.put("messageType", 2);
        map.put("onlineUsers",clients.keySet());
        map.put("fromUsername",username);
        sendMessageToAll(JSON.toJSONString(map), username);
        logger.info("有连接关闭！ 当前在线人数" + onlineCount);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        logger.info("服务端发生了错误"+error.getMessage());
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        logger.info("来自客户端消息:{},客户端的id是:{},用户名是:{}", message, session.getId(), username);
        Map<String,Object> map = new HashMap<>(16);
        JSONObject jsonObject = JSON.parseObject(message);
        SimpleUserRole state = userInfoService.getUserState(jsonObject.get("fromUsername").toString());
        if (!state.getState()) {
            logger.info("这个用户被禁言，消息无法发送");
            return;
        }
        map.put("messageType", 3);
        map.put("message", jsonObject.get("message"));
        map.put("fromUsername", jsonObject.get("fromUsername"));
        map.put("date", jsonObject.get("date"));
        map.put("emotion", jsonObject.get("emotion"));
        if ("所有人".equalsIgnoreCase(jsonObject.get("toUsername").toString())){
            sendMessageToAll(JSON.toJSONString(map), username);
        } else {
            map.put("toUsername", jsonObject.get("toUsername"));
            sendMessageTo(JSON.toJSONString(map), jsonObject.get("toUsername").toString());
        }
        Long formUserId = userInfoService.getIdByNickname(jsonObject.get("fromUsername").toString());
        Long toUsername = userInfoService.getIdByNickname(jsonObject.get("toUsername").toString());
        if (toUsername == null) {
            toUsername = 0L;
        }
        chatService.saveHistoryMessage(map, formUserId, toUsername);
    }


    public static void sendMessageToAll(String message, String fromUserName) {
        for (WebSocket webSocket : clients.values()) {
                webSocket.session.getAsyncRemote().sendText(message);
        }
    }

    private void sendMessageTo(String message, String toUserName) {
        for (WebSocket item : clients.values()) {
            if (item.username.equals(toUserName) ) {
                item.session.getAsyncRemote().sendText(message);
                break;
            }
        }
    }

    private static void addOnlineCount() {
        WebSocket.onlineCount++;
    }

    private static void subOnlineCount() {
        WebSocket.onlineCount--;
    }

}
